You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

87 lines
2.9 KiB

<script setup lang="ts">
import { unwrapApiBody, type ApiResponse } from '../../../../utils/http/factory'
import { formatOccurredOnDisplay, occurredOnToIsoAttr } from '../../../../utils/timeline-datetime'
definePageMeta({
layout: 'public',
})
const route = useRoute()
const publicSlug = computed(() => route.params.publicSlug as string)
const shareToken = computed(() => route.params.shareToken as string)
type Unlisted = {
kind: 'post' | 'timeline' | 'rssItem'
data: Record<string, unknown>
}
const { data, pending, error } = await useAsyncData(
() => `unlisted-${publicSlug.value}-${shareToken.value}`,
async () => {
const path = `/api/public/unlisted/${encodeURIComponent(publicSlug.value)}/${encodeURIComponent(shareToken.value)}`
const res = await $fetch<ApiResponse<Unlisted>>(path)
return unwrapApiBody(res)
},
{ watch: [publicSlug, shareToken] },
)
</script>
<template>
<UContainer class="py-10 space-y-6">
<div v-if="pending" class="text-muted">
加载中…
</div>
<UAlert v-else-if="error" color="error" title="链接无效或内容已不存在" />
<template v-else-if="data">
<UBadge color="neutral">
{{ data.kind }}
</UBadge>
<template v-if="data.kind === 'post'">
<h1 class="text-2xl font-semibold">
{{ data.data.title as string }}
</h1>
<article class="prose dark:prose-invert max-w-none whitespace-pre-wrap">
{{ data.data.bodyMarkdown as string }}
</article>
<PostComments mode="unlisted" :public-slug="publicSlug" :share-token="shareToken" />
</template>
<template v-else-if="data.kind === 'timeline'">
<h1 class="text-2xl font-semibold">
{{ data.data.title as string }}
</h1>
<p
v-if="data.data.occurredOn"
class="mt-2 text-sm tabular-nums text-muted"
>
<time :datetime="occurredOnToIsoAttr(data.data.occurredOn as string | number | Date)">
{{ formatOccurredOnDisplay(data.data.occurredOn as string | number | Date) }}
</time>
</p>
<p v-if="data.data.bodyMarkdown" class="whitespace-pre-wrap">
{{ data.data.bodyMarkdown as string }}
</p>
<a
v-if="data.data.linkUrl"
:href="data.data.linkUrl as string"
target="_blank"
rel="noopener noreferrer"
class="text-primary"
>相关链接</a>
</template>
<template v-else>
<h1 class="text-xl font-semibold">
{{ data.data.title as string || 'RSS 条目' }}
</h1>
<p v-if="data.data.summary" class="text-muted">
{{ data.data.summary as string }}
</p>
<UButton
v-if="data.data.canonicalUrl"
:to="data.data.canonicalUrl as string"
target="_blank"
label="原文"
/>
</template>
</template>
</UContainer>
</template>